<?php

/**
 * Maikuro CMS
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2010, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

final class SitesViewController extends AbstractBackendEntityViewController
{
    /**
     *
     * @var SiteService
     */
    private $siteService;

    /**
     *
     * @var PageService
     */
    private $pageService;

    /**
     *
     * @var TemplateService
     */
    private $templateService;

    /**
     * @var string
     */
    protected $permissionSubject = 'site';

    /**
     *
     * @param BackendApplicationContext $applicationContext
     * @param SiteService $siteService
     * @param PageService $pageService 
     */
    public function __construct(
            BackendApplicationContext $applicationContext,
            SiteService $siteService,
            PageService $pageService,
            TemplateService $templateService) {
        $this->applicationContext = $applicationContext;
        $this->siteService = $siteService;
        $this->pageService = $pageService;
        $this->templateService = $templateService;

        $systemMenu = $this->applicationContext->getMenu()->getMenuItem('system');
        if ($systemMenu != null) {
            $sitesMenu = $systemMenu->getSubMenu()->getMenuItem('sites');
            if ($sitesMenu != null) {
                $sitesMenu->setActive();
            }
        }
    }

    /**
     *
     */
    protected function handleCreateAction()
    {
        $this->request->forward('sites/edit');
    }

    /**
     *
     */
    protected function handleDeleteAction()
    {
        $this->applicationContext->checkPermission('site', Constants::ACCESS_LEVEL_VIEW_EDIT_CREATE_DELETE);

        $siteId = (int) $this->request->getParam(1);

        $currentSite = $this->siteService->getSite($siteId);

        if ($currentSite == null) {
            $this->request->redirectTo('404');
        }

        if ($this->request->isPost()) {
            if ($this->request->getPost('cancel')) {
                $this->request->redirectTo('sites/');
            }
            try {
                $this->siteService->delete($siteId);

                $this->siteService->purgeCache();

                $rootPage = $this->pageService->getRootPage($siteId);
                if ($rootPage != null) {
                    $this->pageService->delete($rootPage, true);
                }

                $this->applicationContext->setCurrentSite(null);
                
                View::getMessenger()->addMessage('Site deleted.');
                $this->request->redirectTo('sites');
            } catch (Exception $e) {
                View::getMessenger()
                    ->addMessage('Site NOT deleted: ' . $e->getMessage(), Messenger::ERROR);
            }

        }

        $pageTitle = Translator::translate('Delete site') . " '$currentSite->name'";
        $this->view->setVar('title', $pageTitle)
                   ->setName('sites/delete')
                   ->render();
        
    }

    /**
     * 
     */
    protected function handleEditAction()
    {
        $this->applicationContext->checkPermission('site', Constants::ACCESS_LEVEL_VIEW_EDIT);

        if ($this->request->isPost() && $this->request->getPost('cancel')) {
            $this->request->redirectTo('sites/');
        }

        $siteId = (int) $this->request->getParam(1);

        $site = $this->siteService->getSite($siteId);

        if ($site == null) {
            $this->applicationContext->checkPermission('site', Constants::ACCESS_LEVEL_VIEW_EDIT_CREATE);
        }

        if ($site !== null) {
            $pageTitle = Translator::translate('Edit site') . " '$site->name'";
        } else {
            $pageTitle = Translator::translate('Create new site');
            $site = $this->siteService->create();
        }

        $model = new SiteViewModel();
        $model->site = $site;
        $model->newCustomField = new CustomFieldEntity();

        $themesDirectoryIterator = new DirectoryIterator($this->applicationContext->getBasePath() . '/themes/');
        foreach ($themesDirectoryIterator as $directory) {
            if ($directory->isDot()) continue;
            $model->themes[] = $directory->getFilename();
        }

        foreach (DateTimeZone::listIdentifiers() as $identifier) {
            $model->timezones[] = $identifier;
        }
        if ($model->site->timezone == null) {
            $model->site->timezone = date_default_timezone_get();
        }

        $mb = new DefaultModelBinder();
        $mb->bindModel($model);

        if ($this->request->isPost()) {
            if (!empty($model->newCustomField->name)) {
                foreach ($model->site->customFields as $customField) {
                    if ($customField->name == $model->newCustomField->name) {
                        $mb->getPropertyMetaData('newCustomField-name')
                           ->getValidationResult()
                           ->setValid(false)
                           ->addValidationMessage("There is already a custom field with the name '{$customField->name}'. Please choose another name.");
                        break;
                    }
                }
            }
            
            if ($mb->isModelValid()) {
                try {

                    if (!empty($model->newCustomField->name)) {
                        $model->site->customFields[] = clone $model->newCustomField;
                        View::getMessenger()->addMessage("Added the custom field '{$model->newCustomField->name}'.");
                        $model->newCustomField = new CustomFieldEntity();
                    }

                    $deleteCustomFieldId = $this->request->getPost('delete-custom-field');
                    if ($deleteCustomFieldId != null) {
                        foreach ($model->site->customFields as $key => $customField) {
                            if ($customField->id == $deleteCustomFieldId) {
                                View::getMessenger()->addMessage("Custom field '{$customField->name}' deleted.");
                                unset($model->site->customFields[$key]);
                                break;
                            }
                        }
                    }

                    if ($site->id == null) {
                        $defaultPage = $this->pageService->create();
                        $defaultPage->title = Translator::translate('Home');
                        $templates = $this->templateService->getTemplates($model->site->theme);
                        $template = array_shift($templates);
                        $defaultPage->template = $template->name;
                    }

                    $this->siteService->save($site);

                    if (isset($defaultPage)) {
                        $defaultPage->siteId = $site->id;
                        $this->pageService->save($defaultPage);
                        $this->pageService->purgeCache($site->id);
                    }

                    $this->siteService->purgeCache();

                    if ($this->applicationContext->getCurrentSite()->id == $site->id) {
                        $this->applicationContext->setCurrentSite($site);
                    }

                    View::getMessenger()->addMessage('Site saved.');

                    $this->request->redirectTo('sites/edit/' . $site->id);

                } catch (Exception $e) {
                    $errorMessage = Translator::translate('Could not save the site: ')
                                  . $e->getMessage();
                    View::getMessenger()
                        ->addMessage($errorMessage, Messenger::ERROR);
                }
            } else {
                View::getMessenger()
                    ->addMessage(Translator::translate('Form not valid.'), Messenger::ERROR);
            }
        }

        $this->view->setVar('title', $pageTitle)
                   ->setVar('model', $model)
                   ->setName('sites/edit')
                   ->render();
    }

    /**
     *
     */
    protected function handleListAction()
    {
        $this->applicationContext->checkPermission('site', Constants::ACCESS_LEVEL_VIEW);

        $pageTitle = Translator::translate('Sites');

        $this->view->setVar('title', $pageTitle)
                   ->setVar('sites', $this->siteService->getSites())
                   ->render();
    }

    /**
     *
     */
    private function handleSiteSelect()
    {
        $siteId = $this->request->getParam(1);
        $site = $this->siteService->getSite((int) $siteId);
        if ($site != null) {
            $this->applicationContext->setCurrentSite($site);
            $this->request->redirectTo($this->request->getParam(3) . '/', 'pages');
        }
    }

    /**
     *
     * @param Request $request
     * @return void
     */
    protected function switchAction(Request $request) {
        if ($request->getParam(0) == 'select') {
            $this->handleSiteSelect();
            return;
        }
        parent::switchAction($request);
    }
}
